package com.foo.common.base.config;

import java.util.List;
import java.util.Properties;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.google.common.collect.Lists;

@Configuration
@PropertySource("classpath:hibernate-localhost-mysql.properties")
@ComponentScan(value = "com.foo", includeFilters = {
		@Filter(type = FilterType.REGEX, pattern = ".*service"),
		@Filter(type = FilterType.REGEX, pattern = ".*dao") })
@EnableTransactionManagement
public class CoreConfig {

	@Autowired
	Environment env;

	@Bean(name = "dataSource")
	public DataSource getDataSource() {
		DriverManagerDataSource dataSource = new DriverManagerDataSource();
		dataSource.setDriverClassName(env
				.getProperty("hibernate.connection.driver_class"));
		dataSource.setUrl(env.getProperty("hibernate.connection.url"));
		dataSource
				.setUsername(env.getProperty("hibernate.connection.username"));
		dataSource
				.setPassword(env.getProperty("hibernate.connection.password"));
		return dataSource;
	}

	@Bean(name = "sessionFactory")
	public LocalSessionFactoryBean getLocalSessionFactoryBean() {

		List<String> availableConfigList = Lists.newArrayList();
		availableConfigList.add("hibernate.dialect");
		availableConfigList.add("hibernate.show_sql");
		availableConfigList.add("hibernate.hbm2ddl.auto");
		availableConfigList.add("hibernate.jdbc.batch_size");
		availableConfigList.add("hibernate.cache.use_second_level_cache");
		availableConfigList.add("hibernate.cache.use_query_cache");
		availableConfigList.add("hibernate.cache.region.factory_class");
		availableConfigList.add("hibernate.generate_statistics");
		availableConfigList.add("hibernate.cache.use_structured_entries");
		availableConfigList.add("hibernate.c3p0.min_size");
		availableConfigList.add("hibernate.c3p0.max_size");
		availableConfigList.add("hibernate.c3p0.timeout");
		availableConfigList.add("hibernate.c3p0.max_statements");

		LocalSessionFactoryBean myBean = new LocalSessionFactoryBean();
		myBean.setDataSource(getDataSource());

		Properties properties = new Properties();
		for (String token : availableConfigList) {
			properties.put(token, env.getProperty(token));
		}

		myBean.setHibernateProperties(properties);
		myBean.setPackagesToScan("com.**.model");
		return myBean;
	}

	@Bean(name = "txManager")
	public HibernateTransactionManager getHibernateTransactionManager() {
		HibernateTransactionManager hibernateTransactionManager = new HibernateTransactionManager(
				getLocalSessionFactoryBean().getObject());
		return hibernateTransactionManager;
	}

}
